
package com.zidian.leader.common.handler;


import android.content.Context;
import android.os.Build;
import android.os.Looper;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.widget.Toast;

import com.zidian.leader.common.util.ErrorLogBuilder;
import com.zidian.leader.common.util.FileUtils;
import com.zidian.leader.common.util.NetworkUtils;
import com.zidian.leader.common.util.StringConstants;

import java.io.FileWriter;
import java.io.PrintWriter;
import java.lang.Thread.UncaughtExceptionHandler;

/**
 * UncaughtException 处理类,当程序发生 Uncaught 异常的时候,由该类来接管程序,记录并发送错误报告.
 * Created by Chen Lang on 2015/10/13.
 */
public class AppUncaughtExceptionHandler implements UncaughtExceptionHandler {

    // AppUncaughtExceptionHandler 实例
    private static AppUncaughtExceptionHandler INSTANCE = new AppUncaughtExceptionHandler();

    // 程序的 Context 对象
    private Context context;

    // 系统默认的 UncaughtException 处理类
    private UncaughtExceptionHandler mDefaultHandler;

    // 保证只有一个 CrashHandler 实例
    private AppUncaughtExceptionHandler() {

    }

    // 获取 CrashHandler 实例 ,单例模式
    public static AppUncaughtExceptionHandler getInstance() {
        return INSTANCE;
    }

    /**
     * 初始化
     */
    public void init(Context context) {
        this.context = context;
        // 获取系统默认的 UncaughtException 处理器
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        // 设置该 AppUncaughtExceptionHandler 为程序的默认处理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    /**
     * 当 UncaughtException 发生时会转入该函数来处理
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        if (!handleUncaughtException(ex) && mDefaultHandler != null) { // 如果用户没有处理则让系统默认的异常处理器来处理
            mDefaultHandler.uncaughtException(thread, ex);
        } else {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
//                Logger.e("AppUncaughtExceptionHandler", "error : ", e);
            }
//            MyApplication.getInstance().exit(context);
        }
    }

    /**
     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
     * @return true:如果处理了该异常信息;否则返回false.
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    private boolean handleUncaughtException(Throwable ex) {
        if (ex == null) {
            return false;
        }
        // 记录异常日志到根目录下 eefung/logs 文件夹下
        try {
            FileWriter fileWriter = new FileWriter(FileUtils.getLogsFile(), true);
            PrintWriter printWriter = new PrintWriter(fileWriter);
            String logStr = ErrorLogBuilder.buildErrorLog(context, StringConstants.STRING_EMPTY, NetworkUtils.getConnectState(), ex);
            printWriter.println(logStr);
            printWriter.println();
            printWriter.close();
        }
        catch(Exception e) {
            Log.e(AppUncaughtExceptionHandler.class.getCanonicalName(), "记录异常日志时出现错误！", e);
        }

        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                // 弹出对话框
                Toast.makeText(context, "程序运行时出现错误，即将退出，请稍后使用", Toast.LENGTH_SHORT).show();

                Looper.loop();
            }
        }.start();
        return true;
    }
}